package com.example.lib5.queue;


import org.junit.Test;

/**
 * 全部都是模于maxsize
 */
public class CircleQueueExample {
    public static void main(String[] args) {
        CircleArray myArrayQueue = new CircleArray(4);
        System.out.println("原始数组遍历：");
        myArrayQueue.showQueue();//此时打印队列应该位无
        System.out.println("添加三个值后遍历");
        myArrayQueue.addQueue(1);
        myArrayQueue.addQueue(2);
        myArrayQueue.addQueue(3);
        myArrayQueue.addQueue(4);//这里显示不会添加
        myArrayQueue.showQueue();
        System.out.println("删除两个");
        System.out.println("取出的值："+myArrayQueue.takeOutQueue());
        System.out.println("取出的值："+myArrayQueue.takeOutQueue());
        System.out.println("遍历");
        myArrayQueue.showQueue();//这里打印为3
        //再次添加两个
//        System.out.println("再次添加两个");
//        myArrayQueue.addQueue(5);
//        myArrayQueue.addQueue(6);
//        myArrayQueue.showQueue();
//        System.out.println("再次删除四个");
//        System.out.println("取出的值："+myArrayQueue.takeOutQueue());
//        System.out.println("取出的值："+myArrayQueue.takeOutQueue());
//        System.out.println("取出的值："+myArrayQueue.takeOutQueue());
//        System.out.println("取出的值："+myArrayQueue.takeOutQueue());
//        myArrayQueue.showQueue();
    }

    private static class CircleArray {
        int maxSize;
        int rear=0;
        int front=0;
        private  int[] arr;

        /**
         *
         * @param max 表示队列的最大长度
         */
        public CircleArray(int max) {
            maxSize=max;
            arr = new int[max];//设置长度
        }
        //遍历数组
        public void showQueue() {
            if (isEmpty()) {
                System.out.println("队列为空，没有数据");
                return;
            }
            for (int i = front; i < front+size(); i++) {
                System.out.println(arr[i%maxSize]);
            }
        }
        //添加数组数据
        public void addQueue(int nextInt) {

            if (isFull()) {//判断队列是否已经满了
                System.out.println("队列最大长度为3，不会再添加");
                return;
            }else {
//                arr[rear+1]=nextInt;//这个普通队列
//                int a=rear%4;
//                arr[rear%4]=nextInt;//添加四个，然后删除两个，再次添加一个，此时rear应该为0，然后再添加应该是1
//                rear++;
                //直接将数据加入
                arr[rear]=nextInt;
                //将rear后移，这里必须考虑取模
                rear=(rear+1)%maxSize;//0,1,2,3,0,1,2,3……
            }
        }
        //取出数据
        public int takeOutQueue() {
            if (isEmpty()) {
               throw new RuntimeException("队列为空，不能取数据");
            }
//            int i = arr[front+1];//普通队列取出
//            int i = arr[front%4];//环形队列取出
//            arr[front+1]=0;//普通队列的
//            arr[front%4]=0;//环形队列
//            front++;
//            return i;
            int i = arr[front];
            front=(front+1)%maxSize;
            return i;
        }

        /**
         * 队列是否已经满了
         * @return true表示已经满了，false表示队列还没有满
         */
        public boolean isFull(){
//            return rear==maxSize-1;//这个是普通队列
            //假设的方式来获取这个结果：这个rear的值最大是3，maxsize这里是4，3+1=maxsize(rear+1)%maxSize,front假设为0不变
//            return (rear+2)%maxSize=(front+1)%maxSize;//
            return (rear+1)%maxSize==front;//
        }

        /**
         * 队列是否为空
         * @return true表示队列为空，false表示队列不为空
         */
        public boolean isEmpty(){
            return rear==front;
        }

        /**
         *
         * @return 返回当前队列的有效数据的个数
         */
        public int size(){
            return (rear+maxSize-front)%maxSize;
        }
        public int headQueue(){
            if (isEmpty()) {
                throw new RuntimeException("队列是空的，没有数据……");
            }
            return arr[front];
        }
    }

    public class MyCircularQueue {
        private int front=0;//队列头
        private int rear=0;//队列尾
        private int usedSize=0;//数据个数
        private int[] arr;//数组
        private int maxSize;
        public MyCircularQueue(int max){
            arr =new int[max];
            maxSize=max;
        }
        public boolean enQueue(int value){
            if(isFull()){
                return false;
            }
            arr[rear]=value;
            usedSize++;
            rear=(rear+1)% arr.length;
            return true;
        }
        //队尾下标加上1在%
        public boolean isFull(){
            if((rear+1)% arr.length==front){
                return true;
            }
            return false;
        }
        public boolean isEmpty(){
            return rear==front;
        }
        public boolean deQueue(int value){
            if(isEmpty()){
                return false;
            }
            arr[front]=value;
            front=(front+1)% arr.length;
            usedSize--;
            return true;
        }
        public int Front(){
            if(isEmpty()){
                throw new UnsupportedOperationException("队列为空");
            }
            return arr[front];
        }
        public int Rear(){
            if(isEmpty()){
                throw new UnsupportedOperationException("队列为空");
            }
            int index=rear == 0 ? arr.length-1 : rear-1;
            return arr[index];
        }

    }


    @Test
    public void modulusTest(){
        //
        int max=4;
        System.out.println(0%4);//不够除，剩余0
        System.out.println(1%4);//不够除，剩余1
        System.out.println(2%4);//不够除，剩余2
        System.out.println(3%4);//不够除，剩余3
        System.out.println(4%4);//够除，除完后剩余0
        System.out.println(5%4);//够除，除完后剩余1
        System.out.println(6%4);//够除，除完后剩余2
        System.out.println(7%4);//够除，除完后剩余3

    }
}
